import traceback
from typing import Optional, Any
from application.model import TortoiseBaseModel
from application.util.LogUtil import write_error_log


class BaseMapper:
    """
    DAO层基类，提供基础的增删改查方法
    """
    orm_model: TortoiseBaseModel = None

    @classmethod
    async def insert(cls, data: dict) -> bool:
        """
        插入数据
        :param data: 数据字典
        :return:
        """
        try:
            # 移除id字段
            if "id" in data.keys():
                data.pop("id")
            # 插入数据
            new_model: TortoiseBaseModel = await cls.orm_model.create(**data)
            await new_model.save()
            return True
        except Exception:
            write_error_log(log_message=f"此数据插入失败：{data}", traceback=traceback.format_exc())
            return False

    @classmethod
    async def batch_insert(cls, model_list: list) -> bool:
        """
        批量插入数据
        :param model_list: ORM模型列表
        :return:
        """
        try:
            await cls.orm_model.bulk_create(model_list)
            return True
        except Exception:
            model_dict_list: list = [model.to_dict() for model in model_list]
            write_error_log(log_message=f"此批量数据插入失败：{model_dict_list}", traceback=traceback.format_exc())
            return False

    @classmethod
    async def update(cls, data: dict) -> bool:
        """
        更新数据
        :param data: 数据字典
        :return:
        """
        try:
            new_model: TortoiseBaseModel = await cls.orm_model.filter(id=data.get("id")).first()
            await new_model.update_from_dict(data=data).save()
            return True
        except Exception:
            write_error_log(log_message=f"此数据更新失败：{data}", traceback=traceback.format_exc())
            return False

    @classmethod
    async def delete(cls, orm_model: TortoiseBaseModel) -> bool:
        """
        删除数据
        :param orm_model: ORM模型
        :return:
        """
        try:
            await orm_model.delete()
            return True
        except Exception:
            write_error_log(log_message=f"此数据删除失败：{orm_model.to_dict()}",
                            traceback=traceback.format_exc())
            return False

    @classmethod
    async def delete_by_field(cls, **kwargs) -> bool:
        """
        根据字段删除数据
        :param kwargs: 字段
        :return:
        """
        orm_model: Optional[TortoiseBaseModel] = await cls.orm_model.filter(**kwargs).first()
        if not orm_model:
            return True
        try:
            await orm_model.delete()
            return True
        except Exception:
            write_error_log(log_message=f"此数据删除失败：{orm_model.to_dict()}",
                            traceback=traceback.format_exc())
            return False

    @classmethod
    async def get_data_by_id(cls, data_id: int) -> Optional[Any]:
        """
        根据数据ID获取数据
        :param data_id: 数据ID
        :return: 数据ORM模型
        """
        return await cls.orm_model.filter(id=data_id).first()

    @classmethod
    async def get_data_list(cls, page: int, page_size: int, **kwargs) -> list[Optional[Any]]:
        """
        获取数据列表（可带筛选条件）
        :param page: 第几页
        :param page_size: 每页多少条数据
        :param kwargs: 查询条件
        :return: 数据ORM模型列表
        """
        return await cls.orm_model.filter(**kwargs).all().limit(page_size).offset((page - 1) * page_size)

    @classmethod
    async def get_data_by_field(cls, **kwargs) -> Optional[Any]:
        """
        根据查询条件获取数据
        :param kwargs: 查询条件
        :return: 数据ORM模型
        """
        return await cls.orm_model.filter(**kwargs).first()

    @classmethod
    async def get_count_by_field(cls, **kwargs) -> int:
        """
        根据条件获取数量
        :param kwargs: 查询条件
        :return: 数量
        """
        return await cls.orm_model.filter(**kwargs).count()